﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using BehaviorFrameworkTest.TestClassses;
using System.ComponentModel;

namespace BehaviorFrameworkTest
{
    [TestClass]
    public class BasicTests
    {
        /// <summary>
        /// Test that a property change event is raised when a property changes.
        /// </summary>
        [TestMethod]
        public void TestPropertyChangedEvent()
        {
            var data = new BasicDataClass();
            var behavior = new BasicBehaviorClass(data);
            bool eventFired = false;
            ((INotifyPropertyChanged) behavior.ViewModel).PropertyChanged += (s,a) => { eventFired = true; };
            behavior.ViewModel.StringProperty = "Test";
            Assert.IsTrue(eventFired);
        }

        //Test that all property change events in the dependency chain fire when a property changes
        [TestMethod]
        public void TestPropertyChangedEvents()
        {
            var data = new BasicDataClass();
            var behavior = new BasicBehaviorClass(data);
           
            var changedProperties = new List<string>();
            
            ((INotifyPropertyChanged)behavior.ViewModel).PropertyChanged += (s, a) => { changedProperties.Add(a.PropertyName); };
            behavior.ViewModel.StringProperty = "Test";
           
            Assert.IsTrue(changedProperties.Count==2);
            Assert.IsTrue(changedProperties.Contains("StringProperty"));
            Assert.IsTrue(changedProperties.Contains("StringIntConcat"));
        }
        
        //Test that changes made to the ViewModel Properties are correctly reflected in the DataModel.
        [TestMethod]
        public void TestDataModelValueChanged()
        {
            var data = new BasicDataClass();
            var behavior = new BasicBehaviorClass(data);

            behavior.ViewModel.StringProperty = "Test";

            Assert.IsTrue(behavior.DataModel.StringProperty == "Test");
        }

        //Test that changes are correctly updating dependent properties in the ViewModel
        [TestMethod]
        public void TestDependentValueChanged()
        {
            var data = new BasicDataClass();
            var behavior = new BasicBehaviorClass(data);

            behavior.ViewModel.StringProperty = "Test";
            behavior.ViewModel.IntProperty = 1;
            Assert.IsTrue(behavior.ViewModel.StringIntConcat == "Test-1");
        }

		[TestMethod]
		public void TestListValueChanged()
		{
			var data = new BasicDataClass();
			var behavior = new BasicBehaviorClass(data);

			behavior.ViewModel.ListProperty.Add("Test");
			Assert.IsTrue(behavior.DataModel.ListProperty.Count == 1);
			Assert.IsTrue(behavior.DataModel.ListProperty.Contains("Test"));
		}
	
		[TestMethod]
		public void TestEnumerableValueChanged()
		{
			var data = new BasicDataClass();
			var behavior = new BasicBehaviorClass(data);

			behavior.ViewModel.EnumerableProperty.Add("Test");
			Assert.IsTrue(behavior.DataModel.EnumerableProperty.Count() == 1);
			Assert.IsTrue(behavior.DataModel.EnumerableProperty.Contains("Test"));
		}

		[TestMethod]
		public void TestListChangedEvent()
		{
			var data = new BasicDataClass();
			var behavior = new BasicBehaviorClass(data);
			var changedProperties = new List<string>();

			((INotifyPropertyChanged)behavior.ViewModel).PropertyChanged += (s, a) => { changedProperties.Add(a.PropertyName); };

			behavior.ViewModel.ListProperty.Add("Test");
			
			Assert.IsTrue(changedProperties.Contains("ListProperty"));
		}
	}
}
